package it.uniroma2.dtk.dt;

import it.uniroma2.dtk.op.IdealOperation;

/**
 * @author Lorenzo Dell'Arciprete, Fabio Massimo Zanzotto
 * Realization of the DefaultAbstractDT, providing the possibility to plug-in the class
 * implementing the vector compoisition function to be used.
 */
public class GenericSubPathDT extends SubPathAbstractDT {

	private IdealOperation op;
	
	public GenericSubPathDT(int randomOffset, int vectorsSize, boolean usePos, double lambda, IdealOperation opImplementation) throws Exception {
		super(randomOffset, vectorsSize, usePos, lambda);
		op = opImplementation;
	}
	
	public GenericSubPathDT(int randomOffset, int vectorsSize, boolean usePos, double lambda, Class<?> opImplementationClass) throws Exception {
		super(randomOffset, vectorsSize, usePos, lambda);
		if (!IdealOperation.class.isAssignableFrom(opImplementationClass))
			throw new Exception("Class "+opImplementationClass+" does not implement interface IdealOperation!");
		op = (IdealOperation) opImplementationClass.newInstance();
		op.initialize(vectorProvider);
	}

	/**
	 * Build a distributed tree and distributed tree fragment generator, with the specified parameters.
	 * The class implementing the vector composition operation must implement interface IdealOperation
	 * and provide a null argument constructor. 
	 * After instantiation, method IdealOperation.initialize(VectorProvider) is invoked.  
	 * 
	 * @param randomOffset: the seed of the RandomVectorGenerator
	 * @param vectorsSize: the size of the vector space
	 * @param lambda: the value for the lambda decaying factor
	 * @param opImplementationClass: the class implementing the vector composition operation
	 * @throws Exception
	 */
	public GenericSubPathDT(int randomOffset, int vectorsSize, double lambda, Class<?> opImplementationClass) throws Exception {
		this(randomOffset, vectorsSize, false, lambda, opImplementationClass);
	}
	
	/**
	 * Build a distributed tree and distributed tree fragment generator, with the specified parameters.
	 * 
	 * @param randomOffset: the seed of the RandomVectorGenerator
	 * @param vectorsSize: the size of the vector space
	 * @param lambda: the value for the lambda decaying factor
	 * @param opImplementation: the implementation of the vector composition operation
	 * @throws Exception
	 */
	public GenericSubPathDT(int randomOffset, int vectorsSize, double lambda, IdealOperation opImplementation) throws Exception {
		this(randomOffset, vectorsSize, false, lambda, opImplementation);
	}

	public GenericSubPathDT(int randomOffset, int vectorsSize, boolean usePos, Class<?> opImplementationClass) throws Exception {
		this(randomOffset, vectorsSize, usePos, 1, opImplementationClass);
	}
	
	public GenericSubPathDT(int randomOffset, int vectorsSize, boolean usePos, IdealOperation opImplementation) throws Exception {
		this(randomOffset, vectorsSize, usePos, 1, opImplementation);
	}
	
	@Override
	public double[] op(double[] v1, double[] v2) throws Exception {
		if (op == null)
			throw new Exception("Composition function class not initialized!");
		return op.op(v1, v2);
	}
	
	public Class<?> getIdealOperation() {
		return op.getClass();
	}

}
